<?php
// +----------------------------------------------------------------------
// | B5Yii2CMF V3.0 [快捷通用基础管理开发平台]
// +----------------------------------------------------------------------
// | Author: 冰舞 <357145480@qq.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace common\services;

use common\services\system\DeptService;
use common\services\system\MenuService;
use common\services\system\RoleService;
use Yii;

class PermissionService
{
    /**
     * 判断是否位超级管理员
     * @param string|integer $userId
     * @return bool
     */
    public static function isAdmin($userId): bool
    {
        return $userId == Yii::$app->params['root_admin_id'];
    }

    /**
     * 前端菜单数
     * @param int $userId
     * @return array
     */
    public static function menuList(int $userId): array
    {
        if (!$userId) return [];
        if (self::isAdmin($userId)) return MenuService::selectAdminWebMenuList('menu');
        return MenuService::selectUserWebMenuList($userId, 'menu');
    }

    /**
     * 前端用戶部门列表
     * @param int $userId
     * @param string $field
     * @return array
     */
    public static function deptList(int $userId, string $field = ''): array
    {
        $list = DeptService::selectDeptByUserId($userId);
        if ($field) return array_unique(array_column($list, $field));
        return $list;
    }

    /**
     * 前端用户角色标识列表
     * @param int $userId
     * @param string $field
     * @return array
     */
    public static function roleList(int $userId, string $field = ''): array
    {
        if (!$userId) return [];
        $list = RoleService::selectRoleByUserId($userId);
        if ($field) return array_column($list, $field);
        return $list;
    }

    /**
     * 特殊关联的权限，未在权限表中添加
     * @return array
     */
    public static function linkPerms(): array
    {
        return [
            'system:role:auth-append' => ['system:role:auth-list'],
            'system:role:auth-remove' => ['system:role:auth-list'],
        ];
    }

    /**
     * 判断权限
     * @param $userId
     * @param string $group
     * @param string $controller
     * @param string $action
     * @return bool
     */
    public static function hasPerm($userId, string $group, string $controller, string $action): bool
    {
        if (!$userId) return false;
        if (self::isAdmin($userId)) return true;

        // 约定 index、common、 public、home 控制器不走授权
        // info方法以及 find或get开头的方法不走授权
        $notAuthController = ['public', 'common', 'index', 'home'];
        $notAuthAction = ['info'];
        if (in_array($controller, $notAuthController) || in_array($action, $notAuthAction) || substr($action, 0, 4) === 'find' || substr($action, 0, 3) === 'get') return true;

        // 角色列表
        $roleList = self::roleList($userId, 'id');
        if (!$roleList) return false;

        // 角色菜单列表
        $roleMenuList = RoleService::selectRoleMenuListByRole($roleList);
        if (!$roleMenuList) return false;

        $perms = ($group ? $group . ':' : '') . $controller . ':' . $action;

        // 关联权限
        $linkPerms = self::linkPerms();
        $perms = $linkPerms[$perms] ?? $perms;
        if (!is_array($perms)) $perms = [$perms];

        foreach ($perms as $perm) {
            $menuInfo = MenuService::selectInfoByPerms($perm);
            if ($menuInfo && in_array($menuInfo['id'], $roleMenuList)) return true;
        }
        return false;
    }
}
